﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using EpiNEXT.Core.Fields;

namespace EpiNEXT.Core.Validation
{
    [Serializable()]
    public sealed class Token
    {
        private string _positionString = "L";
        private TokenPositions _position = TokenPositions.Left;
        private string _tokenTypeString = "FieldName";
        private TokenTypes _tokenType = TokenTypes.FieldName;

        [XmlIgnore]
        public TokenPositions Position
        {
            get { return this._position; }
            set
            {
                if (Position != value)
                {
                    this._position = value;
                    switch (Position)
                    {
                        default:
                        case TokenPositions.Left:
                            PositionString = "L";
                            break;
                        case TokenPositions.Right:
                            PositionString = "R";
                            break;
                        case TokenPositions.Center:
                            PositionString = "C";
                            break;
                    }
                }
            }
        }

        [XmlAttribute("Pos")]
        public string PositionString
        {
            get { return this._positionString; }
            set
            {
                if (!PositionString.Equals(value))
                {
                    this._positionString = value;
                    switch (PositionString)
                    {
                        default:
                        case "L":
                            Position = TokenPositions.Left;
                            break;
                        case "C":
                            Position = TokenPositions.Center;
                            break;
                        case "R":
                            Position = TokenPositions.Right;
                            break;
                    }
                }
            }
        }

        [XmlIgnore]
        public TokenTypes TokenType
        {
            get { return this._tokenType; }
            set
            {
                if (TokenType != value)
                {
                    this._tokenType = value;
                    switch (TokenType)
                    {
                        default:
                        case TokenTypes.FieldName:
                            TokenTypeString = "FieldName";
                            break;
                        case TokenTypes.Function:
                            TokenTypeString = "Function";
                            break;
                        case TokenTypes.Literal:
                            TokenTypeString = "Literal";
                            break;
                    }
                }
            }
        }

        [XmlAttribute("Type")]
        public string TokenTypeString
        {
            get { return this._tokenTypeString; }
            set
            {
                if (!TokenTypeString.Equals(value))
                {
                    this._tokenTypeString = value;
                    switch (TokenTypeString)
                    {
                        default:
                        case "FieldName":
                            TokenType = TokenTypes.FieldName;
                            break;
                        case "Function":
                            TokenType = TokenTypes.Function;
                            break;
                        case "Literal":
                            TokenType = TokenTypes.Literal;
                            break;
                    }
                }
            }
        }

        [XmlText]
        public string Value { get; set; }

        public Token()
            : base()
        {

        }

        public object GetValue(Record record)
        {
            DataEntryInstrument form = record.Form;

            if (TokenType == TokenTypes.Literal)
            {
                return Value;
            }
            else if (TokenType == TokenTypes.FieldName)
            {
                string fieldName = this.Value;

                if(form.Fields.Contains(fieldName)) 
                {
                    IField field = form.Fields[fieldName];

                    object fieldValue = record.GetFieldData(field);
                    return fieldValue;
                }
            }
            else if (TokenType == TokenTypes.Function)
            {
                throw new NotImplementedException();
            }

            return null; // Throw exception instead?
        }
    }
}
